package net.lab1024.sa.admin.module.upstream.box.cases.impl;

import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.upstream.api.painet.PainetBoxApi;
import net.lab1024.sa.admin.module.upstream.api.painet.constants.PainetConstant;
import net.lab1024.sa.admin.module.upstream.api.painet.enumeration.ProcessStatusEnum;
import net.lab1024.sa.admin.module.upstream.api.painet.request.BoxListQueryFrom;
import net.lab1024.sa.admin.module.upstream.api.painet.response.BoxListResponse;
import net.lab1024.sa.admin.module.upstream.box.UpstreamBoxService;
import net.lab1024.sa.admin.module.upstream.box.cases.UpstreamCase;
import net.lab1024.sa.admin.module.upstream.box.domain.UpstreamBoxQueryForm;
import net.lab1024.sa.admin.module.upstream.box.domain.UpstreamBoxEntity;
import net.lab1024.sa.base.common.constant.UpstreamConst;
import net.lab1024.sa.base.common.enumeration.UpstreamEnum;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static net.lab1024.sa.base.common.constant.UpstreamConst.PAINET_UPSTREAM_SYMBOL;

/**
 * 派盒子业务
 */
@Slf4j
@Component(PAINET_UPSTREAM_SYMBOL)
public class PainetBoxUpstreamCase implements UpstreamCase {

    private final PainetBoxApi painetBoxApi;

    private final UpstreamBoxService upstreamBoxService;

    public PainetBoxUpstreamCase(PainetBoxApi painetBoxApi,
                                 UpstreamBoxService upstreamBoxService) {
        this.painetBoxApi = painetBoxApi;
        this.upstreamBoxService = upstreamBoxService;
    }

    @Override
    public void updateUpstreamDetail() {
        UpstreamEnum upstreamEnum = upstreamEnum();
        // 查询条件
        UpstreamBoxQueryForm queryForm = new UpstreamBoxQueryForm();
        queryForm.setUpstreamCode(upstreamEnum.getValue());
        // 查询条数偏移量
        int offset = 100;
        // 从第一页开始for循环
        for (int i = 1; ; i++) {
            // 查询的开始位置
            int begin = (i - 1) * offset;
            List<UpstreamBoxEntity> entities =
                    upstreamBoxService.queryByOffsetAndCriteria(begin, offset, queryForm);
            // 为空跳出循环
            if (entities.isEmpty()) {
                break;
            }

            // 按上游的id查询上游的数据
            List<String> upstreamIds =
                    entities.stream().map(UpstreamBoxEntity::getUpstreamId).collect(Collectors.toList());
            BoxListQueryFrom from = BoxListQueryFrom
                    .builder()
                    .supplierBoxIds(upstreamIds)
                    .build();
            List<BoxListResponse.Box> boxList = null;
            try {
                boxList = painetBoxApi.getBoxList(from);
            } catch (Exception e) {
                log.error("更新派盒子设备信息，在第{}到{}条时出错", begin, begin + offset, e);
                throw new RuntimeException(e);
            }
            if (boxList == null || boxList.isEmpty()) {
                log.info("查询{}上游无数据", upstreamEnum.getDesc());
                return;
            }
            // 将盒子列表转为以供应商盒子id为key的map
            Map<String, BoxListResponse.Box> boxMap = boxList.stream()
                    .collect(
                            Collectors.toMap(
                                    BoxListResponse.Box::getSupplierBoxId,
                                    box -> box,
                                    (existing, replacement) -> existing
                            )
                    );
            // 循环更新对应信息
            for (UpstreamBoxEntity entity : entities) {
                // 获取盒子信息，为空直接跳出本次循环
                BoxListResponse.Box box = boxMap.get(entity.getUpstreamId());
                if (box == null) {
                    continue;
                }
                // 对应属性赋值
                entity.setNatType(box.getTcpNatType());
                entity.setUpnpFlag(box.getUpnp());
                String processDesc = ProcessStatusEnum.getDescByStatus(box.getProcessStatus());
                entity.setServiceStatus(processDesc);
                entity.setOnlineFlag(PainetConstant.ONLINE.equals(box.getOnline()));
                entity.setBusinessFlag(!ProcessStatusEnum.UNUSABLE.getStatus().equals(processDesc));
                Double pressBandwidth = box.getPressBandwidth();
                entity.setOutMaxBandwidth(pressBandwidth != null ? pressBandwidth.intValue() : 0);
                entity.setIp(box.getBoxId());
                entity.setIsp(box.getIsp());
                entity.setProvince(box.getProvince());
                entity.setCity(box.getCity());
                entity.setCpuCores(box.getCpuCores());
                Long memorySize = box.getMemorySize();
                if (memorySize != null) {
                    int sizeGb = BigDecimal.valueOf(memorySize)
                            .divide(BigDecimal.valueOf(UpstreamConst.GB), RoundingMode.CEILING)
                            .intValue();
                    entity.setMemorySize(sizeGb);
                }
                List<BoxListResponse.DiskInfo> diskInfos = box.getDiskInfos();
                if (diskInfos != null && !diskInfos.isEmpty()) {
                    long diskSize = diskInfos.stream().mapToLong(BoxListResponse.DiskInfo::getDiskSize).sum();
                    int sizeGb = BigDecimal.valueOf(diskSize)
                            .divide(BigDecimal.valueOf(UpstreamConst.GB), RoundingMode.CEILING)
                            .intValue();
                    entity.setDiskSize(sizeGb);
                }
            }
            // 批量更新
            upstreamBoxService.updateBatch(entities);
        }
    }

    @Override
    public UpstreamEnum upstreamEnum() {
        return UpstreamEnum.PAINET_BOX;
    }
}
